<!--
 * @Author: qiye
 * @LastEditors: qiye
 * @description: page description
 * @Date: 2024-01-17 15:55:18
 * @LastEditTime: 2024-02-04 14:08:32
-->
<script setup lang="ts">
import { ikTree } from 'iking-utils'
import { filterForm } from './widget-utils'
import { pageManage as api, modelManage } from '@/MainApp/apis/manage-design'
import ModelManage from '@/MainApp/views/function-design/model-manage/model-manage.vue'
import { pageApi } from '@/MainApp/apis/application'

const props = defineProps({
  application: {
    type: Object,
    default: null
  },
  page: {
    type: Object,
    default: () => ({})
  },
  visible: {
    type: Boolean,
    default: false
  },
  defaultTab: {
    type: String,
    default: 'design'
  }

})

const emit = defineEmits(['update:visible', 'back'])

onMounted(() => {
  console.log('props.defaultTab', props.defaultTab)
})

const { msgError, msgSuccess } = useMessage()

const model = computed({
  get: () => {
    return props.visible
  },
  set: (value: boolean) => {
    emit('update:visible', value)
  }
})

const baseUrl = ref(import.meta.env.VITE_APP_API_BASEURL)

/** 设计相关 begin */

// 表单项类型映射
const TypeMap: any = {
  /** 表单有 */
  // 单行输入
  input: 'INPUT',
  // 多行输入
  textarea: 'TEXTAREA',
  // 计数器
  number: 'NUMBER',
  // 单选项
  radio: 'RADIO',
  // 多选项
  checkbox: 'CHECKBOX',
  // 下拉选项
  select: 'SELECT',
  // 时间
  time: 'TIME',
  // 时间范围
  'time-range': 'TIME_RANGE',
  // 日期
  date: 'DATE',
  // 日期范围
  'date-range': 'DATE_RANGE',
  // 开关
  switch: 'SWITCH',
  // 评分
  rate: 'RATE',
  // 颜色选择
  color: 'COLOUR_PICKER',
  // 滑块
  slider: 'SLIDER',
  // 静态文字
  'static-text': 'STATIC_TEXT',
  // HTML
  'html-text': '',
  // 按钮
  button: 'BUTTON',
  // 分隔线
  divider: 'DIVIDER',
  // 文件上传
  'ik-upload-file': 'FILE_UPLOAD',
  // 图片上传
  'ik-upload-image': 'IMAGE_UPLOAD',
  // 树形选择
  'tree-select': 'TREE_SELECT',

  // 人员选择
  'ik-picker': 'USER_PICKER',
  // 部门选择
  'ik-dept-picker': 'DEPT_PICKER',
  // 组织选择
  'ik-organization-picker': 'ORGANIZATION_PICKER',
  // 角色选择
  'ik-role-picker': 'ROLE_PICKER',
  // 岗位选择
  'ik-post-picker': 'POST_PICKER'

}
// 已配置的表单列表
const formList = computed<any[]>(() => {
  if (!formModel.jsonObj) {
    //
    return []
  }

  const formList = filterForm(formModel.jsonObj.widgetList)
  const formConfig = JSON.parse(JSON.stringify(formModel.jsonObj.formConfig))

  const result = formList.map((item: any) => {
    // 将表单的表达式设置给全局配置
    formConfig.expressions = item.options.expressions

    const obj = {
      // 对应 widget.id
      code: item.id,
      name: item.options.label,
      modelId: item.options.modelId,
      widgets: item.widgetList.map((child: any) => ({
        name: child.options.keyName,
        label: child.options.label,
        type: TypeMap[child.type],
        required: child.options.required

      })),
      json: JSON.stringify({
        widgetList: item.widgetList,
        formConfig: formModel.jsonObj.formConfig
      })
    }

    return obj
  })
  if (result.length === 1)
    formModel.initiateFormId = result[0].code

  return result
})
/** 设计相关 end */
// 设计器引用
const designerRef = ref<any>(null)
// 加载状态
const loading = ref<boolean>(false)

class FormModel {
  // id: string | null = null
  // 英文标识
  // name = ''
  // 菜单名称
  // title = ''
  description = ''
  // 路由地址
  // link = ''
  // 图标
  // icon = ''
  // 组件路径
  // component = ''
  // 后端字段
  json: string = ''
  // 前端字段
  jsonObj: any = null
  modelIds: string[] = []
  // 关联审批
  relateToApprove = false
  // 审批发起表单
  initiateFormId = ''
  // 审批节点表单列表
  approveNodeForms = []
  // 父菜单 ID
  parentMenuId = ''

  /** 新页面字段 begin */
  appCode = ''
  appId = ''
  // 组件路径
  component = ''
  // 图标
  icon = ''
  // 唯一标识
  id = ''
  // 路由地址
  link = ''
  // 英文标识
  name = ''
  // 父菜单 id
  parentId = ''
  type = ''
  typeName = ''
  /** 新页面字段 end */
}
const formModel = reactive(new FormModel())

/** 请求域 begin */
const token = useToken()
// 初始化域请求头
const initHeaderArr = () => {
  const headers: any = {}
  // setDomainHeader(headers)
  const result: any [] = Object.keys(headers).map((key: string): any => ({ name: key, value: headers[key] })) ?? []
  return result
}
const headerArr = initHeaderArr()
/** 请求域 end */

/** 页面设置相关 begin */
const pageFormRef = ref<any>(null)
const currentSettingMenu = ref<any>('basic')
/** 页面设置相关 end */

/** 模型 begin */
const modelState = reactive<any>({
  visible: false,
  modelList: []
})
const modelMethods = {
  setModels: () => {
    let models = modelState.modelList.filter((item: any) => formModel.modelIds.includes(item.id))
    // 获取子模型
    let descendant: any = []
    for (const model of models) {
      const des = ikTree.descendant(model, { childrenField: 'slaveModels' }) ?? []
      descendant = descendant.concat(des)
    }
    // 合并
    let modelIds = descendant.map((item: any) => item.modelId).concat(models.map((item: any) => item.id))
    // 去重
    modelIds = [...new Set(modelIds)]
    models = modelState.modelList.filter((item: any) => modelIds.includes(item.id))
    editState.designerConfig.models = models
  },

  initModelList: async () => {
    const ret = await modelManage.selectAll(true)
    if (!ret.success) {
      msgError(ret.msg)
      return
    }
    modelState.modelList = ret.data
  }
}
onMounted(() => {
  modelMethods.initModelList()
})
/** 模型 end */
/** 保存 begin */
const saveMethods = {

  submit: async () => {
    try {
      await pageFormRef.value?.validate()
    }
    catch (err) {
      console.error(err)
      return
    }

    if (editState.activeTab === 'design') {
      //
      formModel.jsonObj = designerRef.value?.getFormJson()
    }

    const target = formList.value?.find((item: any) => item.code === formModel.initiateFormId)
    const params = {
      ...formModel,
      json: formModel.jsonObj ? JSON.stringify(formModel.jsonObj) : null,
      initiateForm: target,
      approveNodeForms: formList.value?.filter((item: any) => item.code !== target?.code) ?? [],
      appCode: props.application?.code
    }

    loading.value = true
    let res = null
    if (editState.activeTab === 'design') {
      res = await pageApi.update(params)
    }
    else {
      // // const param = {
      // //   id: '',
      // //   appId: '',
      // //   appCode: '',
      // //   parentId: '',
      // //   name: '',
      // //   icon: '',
      // //   link: '',
      // //   component: '',
      // //   type: ''
      // // }
      // copyValue(param, params)
      res = await pageApi.update(params)
    }
    loading.value = false
    if (!res.success) {
      msgError(res.msg)
      return
    }
    msgSuccess(res.msg)
  }
}
/** 保存 end */

const editState = reactive<any>({
  tabs: [],
  details: null,
  title: '',
  operation: '',
  visible: false,
  activeTab: props.defaultTab,
  json: '',
  // 全局表单配置
  globalFormConfig: {
    datasourceResponseConvert: '  const res = result.data;\n  const resultData = {\n    ...res,\n    status: res.success === true ? \'success\' : \'error\',\n    message: res.msg,\n    data: res.data\n  }\n  \n  if(resultData.status === \'error\'){\n     throw Error(resultData.message);\n  }\n  \n  result.data = resultData;\n  \n  return result;',
    dataSourceHost: import.meta.env.VITE_APP_API_BASEURL,
    uploadUrl: import.meta.env.VITE_APP_UPLOAD_URL,
    downloadUrl: import.meta.env.VITE_APP_DOWNLOAD_URL
  },
  designerConfig: {
    formTemplates: true,
    logoHeader: false,
    // 模型
    models: []
  } as any,
  globalDatasourceHeaders: [
    {
      name: 'Authorization',
      value: token
    },
    ...headerArr
  ],
  // 模板列表
  formTemplates: [],
  // 默认加载的模板
  defaultTemplate: ''
})

const editMethods = {
  // 初始化 tabs
  initTabs: () => {
    const tabs = [{ id: 'setting', label: '页面设置' }]
    if (props.page.type !== 'BUSINESS') {
      tabs.unshift({ id: 'design', label: '页面设计' })
      tabs.push({ id: 'model', label: '模型管理' })
    }
    editState.tabs = tabs
  },
  loadTemplate: async () => {
    const ret = await api.listTemplate()
    if (!ret.success) {
      msgError(ret.msg)
      return
    }
    const templates = ret.data.map((item: any) => ({ title: item.title, description: item.description, jsonData: JSON.parse(item.jsonData) }))
    for (const item of templates) {
      (item.jsonData.formConfig.dataSources ?? []).forEach((ds: any) => {
        const url = ds.requestURL

        const searchIndex = url.indexOf('?')
        if (searchIndex > -1) {
          const searchStr = url.substring(searchIndex)
          const searchParams = new URLSearchParams(searchStr)
          searchParams.delete('page')
          searchParams.append('page', formModel.id)
          const searchString = searchParams.toString()
          ds.requestURL = `${url.substring(0, searchIndex)}?${searchString}`
        }
        else {
          //
          ds.requestURL = `${ds.requestURL}?page=${formModel.id}`
        }
      })
    }
    editState.formTemplates = templates
  },
  initSetting: () => {
    // 页面设置
    copyValue(formModel, props.page)
    console.log('formModel ', formModel)
  },
  initDesign: async () => {
    await editMethods.initDetails()
    // editState.activeTab = 'design'
    // TODO 将数据库里的设置数据赋值给设置器
    copyValue(formModel, editState.details)

    if (!formModel.jsonObj) {
      if (editState.details.json) {
      //
        formModel.jsonObj = JSON.parse(editState.details.json)
      }
    }
    // debugger
    // formModel.modelIds = editState.details.models?.map((item: any) => item.id) ?? []
    formModel.initiateFormId = editState.details.initiateForm?.code

    editState.visible = false
    // 加载模板
    await editMethods.loadTemplate()
    modelMethods.setModels()
    editState.visible = true
    // 修改
    if (formModel.jsonObj) {
      //
      nextTick(() => {
        designerRef.value?.setFormJson(formModel.jsonObj)
      })
    }
    else {
      if (props.page.type === 'APPROVE') {
        //
        const template: any = editState.formTemplates.find((item: any) => item.title === '审批表格')
        if (template) {
          nextTick(() => {
            designerRef.value?.setFormJson(template.jsonData)
          })
        }
      }
      else {
        nextTick(() => {
          designerRef.value?.clearDesigner()
        })
      }
    }
  },
  init: async () => {
    if (editState.activeTab === 'setting') {
      editMethods.initSetting()
    }
    else if (editState.activeTab === 'design') {
      //
      editMethods.initDesign()
    }
  },
  save: () => {
    console.log('save ...')
    saveMethods.submit()
  },
  listForm: () => {
  },

  handleTabChange: async (tab: string) => {
    console.log('handleTabChange tab ', tab)
    editState.activeTab = tab
    if (tab !== 'design') {
      if (designerRef.value) {
        //
        formModel.jsonObj = designerRef.value.getFormJson()
      }

      if (tab === 'setting') {
        // 页面设置
        editMethods.initSetting()
      }
    }
    else {
      editMethods.initDesign()
    }
  },

  initDetails: async () => {
    if (props.page.type !== 'BUSINESS') {
      const res = await pageApi.details(props.page.id)
      if (!res.success) {
      //
        msgError(res.msg)
        return
      }
      editState.details = res.data
    }
  }
}

editMethods.initTabs()

onMounted(() => {
  // editMethods.initDetails()
  editMethods.init()
})
</script>

<template>
  <el-dialog

    v-model="model"
    class="page-manage-dialog-edit"
    fullscreen
    append-to-body
    :show-close="false"
  >
    <template #header>
      <div style="position: relative;" class="header">
        <div class="left-area">
          <IkSvgIcon name="iksvg_zuoyi" class="margin-left-small" @click="emit('back')" />
          <IkLinearIcon :size="32" :icon="application.icon" :background-color="application.backgroundColor" />
          <span class="application-name margin-left-normal fw-bold">
            {{ application.name }}
          </span>
          <IkSvgIcon name="iksvg_shouqi-copy" />
          <span class="page-name fw-regular color-secondary">
            {{ page.name }}
          </span>
        </div>

        <IkPageTabs
          :model-value="editState.activeTab"
          split
          default-slot
          :tabs="editState.tabs"
          @tab-click="editMethods.handleTabChange"
        />
      </div>
    </template>
    <div v-if="editState.activeTab === 'setting'" class="setting-box">
      <div class="left-bar">
        <el-menu default-active="basic" @select="currentSettingMenu = $event">
          <el-menu-item index="basic">
            <template #title>
              <!-- IkSvgIcon -->
              <span>
                <IkSvgIcon
                  :size="18"
                  :start-margin="false"
                  disabled
                  name="iksvg_shezhi2"
                />
                <span>{{ '基础设置' }}</span>
              </span>
            </template>
          </el-menu-item>
          <!-- <el-menu-item index="advance">
            <template #title>

              <span>
                <IkSvgIcon
                  :size="18"
                  :start-margin="false"
                  disabled
                  name="iksvg_shezhi2"
                />
                <span>{{ '高级设置' }}</span>
              </span>
            </template>
          </el-menu-item> -->
        </el-menu>
      </div>
      <div class="main-content">
        <div class="main-content-body">
          <el-scrollbar>
            <el-form
              ref="pageFormRef"
              label-width="80px"
              label-position="top"
              class="page-form"
              :model="formModel"
            >
              <template v-if="currentSettingMenu === 'basic'">
                <el-form-item label="页面名称" prop="name" :rules="[{ required: true, message: '请输入页面名称' }]">
                  <el-input v-model="formModel.name" :maxlength="45" clearable />
                </el-form-item>

                <el-form-item label="页面描述">
                  <el-input
                    v-model="formModel.description"
                    placeholder="请输入页面描述"
                    type="textarea"
                    :maxlength="200"
                    show-word-limit
                    clearable
                  />
                </el-form-item>
                <template v-if="page.type !== 'BUSINESS'">
                  <el-form-item label="关联模型">
                    <el-select
                      v-model="formModel.modelIds"
                      multiple
                      clearable
                      placeholder="请选择关联模型"
                    >
                      <el-option
                        v-for="item in modelState.modelList"
                        :key="item.code"
                        :value="item.id"
                        :label="item.name"
                      />
                    </el-select>
                  </el-form-item>
                </template>
                <el-form-item label="图标" :rules="[{ required: true, message: '请选择图标' }]">
                  <IkFlowIconPicker v-model="formModel.icon" type="twoColor" />
                </el-form-item>
              </template>

              <template v-if="page.type === 'BUSINESS'">
                <el-form-item label="路由地址">
                  <el-input
                    v-model="formModel.link"
                    placeholder="请输入路由地址"
                    :maxlength="100"
                    clearable
                  />
                </el-form-item>
                <el-form-item label="组件路径">
                  <el-input
                    v-model="formModel.component"
                    placeholder="请输入组件路径"
                    :maxlength="100"
                    clearable
                  />
                </el-form-item>
              </template>
            </el-form>
          </el-scrollbar>
        </div>
      </div>
    </div>
    <div v-if="editState.activeTab === 'design'" class="designer-box">
      <v-form-designer
        v-if="editState.visible"
        ref="designerRef"
        :global-dsv="{ apiHost: baseUrl }"
        :designer-config="editState.designerConfig"
        :global-form-config="editState.globalFormConfig"
        :form-templates="editState.formTemplates"
        :global-datasource-headers="editState.globalDatasourceHeaders"
      />
    </div>
    <div v-if="editState.activeTab === 'model'" class="model-box">
      <ModelManage />
    </div>
    <template #footer>
      <div class="dialog-footer">
        <!-- <el-button text bg @click="editMethods.close">取消</el-button> -->
        <el-button type="primary" :loading="loading" @click="editMethods.save">
          保存
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<style lang="scss" scoped>
.setting-box{
  display: flex;
  background-color: var(--color-bg-page);

  .left-bar {
      width: 290px;
      flex-shrink: 0;
      background-color: var(--color-bg-page-content);
      padding: 16px;

      :deep(.el-menu){
        --el-menu-base-level-padding: 10px;

        border-right: none;

        .el-menu-item{
          height: 40px;
          border-radius: var(--border-radius-normal);
        }

        .el-menu-item.is-active {
          background-color: var(--color-bg-page-tag);
          color: var(--color-font-normal);
        }
      }

    }

    .main-content{
      flex-grow: 1;
      padding: 28px 28px 20px;

      .main-content-body{
        height: 100%;
        background-color: var(--color-bg-page-content);
        display: flex;
        flex-direction: column;

        .page-form{
          width: 50%;
          flex-grow: 1;
          padding: 32px;
        }

        .footer{
          flex-shrink: 0;
          height: 60px;
          border-top: 1px solid var(--color-divider);
          display: flex;
          align-items: center;
          justify-content: end;
          padding-right: 28px;

          .save-button{
            min-width: 88px;
          }
        }
      }
    }
}

.model-box{
  height: 100%;

  .ik-page-main.gl-padding{
    height: 100%  !important;
    width: 100%;
    margin: 0;
    position:static;
    // display: flex;

  }
}
</style>

<style lang="scss">
.page-manage-dialog-edit.is-fullscreen{
  .header{
    display: flex;

    .left-area{
      display: flex;
      align-items: center;
      flex-shrink: 0;
      width: 500px;

      .application-name, .page-name{
        font-size: 16px;
      }
    }
  }

  & > .el-dialog__body{
    padding: 0;
    max-height: none;
    height: calc(100vh - 114px);
  }

  .event-setting .el-dialog__body{
    padding: 28px 32px;
  }

  .dialog-container .el-dialog__body{
    padding: 28px 32px;
  }

  .setting-form .el-switch__core{
    width: 40px;
  }

  .designer-box, .setting-box{
    height: calc(100vh - 114px);
    overflow-y:auto;
  }

  .el-dialog__footer:has(> .dialog-footer){
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 60px;
    // padding: 0;
    padding: 10px var(--el-dialog-padding-primary);
  }

  & > .el-dialog__header{
    padding: 0;

    .el-tabs.gl-padding{
      margin: 0;
    }

    .ik-tabs-split.gl-padding{
      margin: 0;
    }

    .el-tabs__header.is-top{
      left: calc(50% - 400px);
    }

    .el-tabs__nav.is-top{
      // transform: translateX(calc(100%)) !important;
    }
  }

}
</style>
